package com.gao.config;


import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;


/**
 * @Description TODO  redis配置类  配置序列化器  未设置过期时间  需要自行配置
 * @Author anshenghui
 * @Date 2020/1/14 8:10
 * @Version 1.0
 */
@Configuration
@EnableCaching
@Slf4j
public class RedisConfig {

    /**
     *   fastjson的redis序列化器不是自己创建，在低版本中由自己创建并实现RedisSerializer接口，但是在目前版本中
     *   已经提供了默认的序列化器，故不需要在自己写了
     *   另外，springboot1.x 与  springboot2.x配置CacheManager的方式不一样，具体可以翻阅redis的自动配置类翻阅源码可以得到，
     *   可以具体根据自己的需要进行剔除
     */

    //cachemanager  针对@annon
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()));
        RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(config)
                //此设置对put evict  加锁
                .transactionAware()
                .build();
        log.debug("自定义RedisCacheManager加载完成");
        return redisCacheManager;
    }

    //针对redisTemplate.ops或bound
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setKeySerializer(keySerializer());
        redisTemplate.setHashKeySerializer(keySerializer());
        redisTemplate.setValueSerializer(valueSerializer());
        redisTemplate.setHashValueSerializer(valueSerializer());
        log.debug("自定义RedisTemplate加载完成");
        return redisTemplate;
    }

    //key的序列化器
    private RedisSerializer<String> keySerializer() {
        return new StringRedisSerializer();
    }

    //value的序列化器
    private RedisSerializer<Object> valueSerializer() {
        return new GenericFastJsonRedisSerializer();
    }
}
